﻿using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using BusinessLayer;
using DataLayer;
using EntLib;
using Rss;
using Database.IVLE;

/// <summary>
/// Summary description for JSON
/// </summary>
[WebService(Namespace = "http://nexus.nus.edu.sg/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class JSON : WebServiceBase
{

   public JSON()
   {

      //Uncomment the following line if using designed components 
      //InitializeComponent(); 
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public JSON_Tabs UserFirstLoad()
   {
      using (new EntTimedLog(UserName, "JSON:UserFirstLoad"))
      {
         JSON_Tabs result = new JSON_Tabs();
         ArrayList Tabs = new ArrayList();

         using (var db = DatabaseHelper.GetDashboardData())
         {
            Guid UserGuid = UserKey;
            #region Check for New Role Tabs
            //Check if this guy has any roletabs that has not been added to his list
            var RTs = (from p in db.aspnet_UsersInRoles
                       join T in db.RoleTabs on p.RoleId equals T.RoleID
                       join UT in
                          (from x in db.UserTabs where x.UserID == UserGuid select x) on new { T.RoleID, T.TabId } equals new { UT.RoleID, UT.TabId } into UTJ
                       from UT in UTJ.DefaultIfEmpty()
                       where p.UserId == UserGuid
                       select new { T.TabId, T.RoleID, T.AccessLevel, AddTab = UT.TabId == null ? true : false }).Distinct();

            if (RTs.Count() > 0)
            {
               //get the last order value
               var order = (from p in db.UserTabs
                            where p.UserID == UserGuid
                            orderby p.Order descending
                            select p.Order).First();

               //add 1 to it
               order++;

               //Got new tabs that's not added
               foreach (var RT in RTs)
               {
                  if (RT.AddTab)
                  {
                     var UT = new UserTab();
                     UT.AccessLevel = RT.AccessLevel;
                     UT.Order = order++;
                     UT.TabId = RT.TabId;
                     UT.UserID = UserGuid;
                     UT.RoleID = RT.RoleID;
                     DatabaseHelper.Insert<UserTab>(UT);
                  }
               }
            }
            #endregion

            //Get user setting
            var dUserSetting = (from p in db.UserSettings
                                where p.UserId == UserKey
                                select p);
            if (dUserSetting.Count() > 0)
            {
               result.ActiveTabID = dUserSetting.Single().ActiveTab;
            }
            else
            {
               //record went missing??? add him in
               var newUserSetting = new UserSetting();
               newUserSetting.LoginCount = 1;
               newUserSetting.UserId = UserKey;

               //find his last active tab
               var myTabs = (from p in db.UserTabs
                             where p.UserID == UserGuid
                             select p.TabId);
               if (myTabs.Count() > 0)
               {
                  newUserSetting.ActiveTab = myTabs.First();
                  DatabaseHelper.Insert<UserSetting>(newUserSetting);
               }
               else
               {
                  throw new ApplicationException("You do not have any tabs to your UserID");
               }
            }

            //get all the user Tabs and properties
            var dUserTabs = (from UP in db.UserTabs
                             join P in db.Tabs on UP.TabId equals P.ID
                             where UP.UserID == UserKey && UP.Deleted == false
                             orderby UP.Order
                             select new { UP.AccessLevel, UP.TabId, UP.Order, TabRecord = P });

            foreach (var obj in dUserTabs)
            {
               bool found = false;
               foreach (JSON_Tab T in Tabs)
               {
                  if (T.id == obj.TabId)
                  {
                     T.AccessLevel = TabAccessLevelFunctions.UpdateAccessLevels(T.AccessLevel, obj.AccessLevel);
                     found = true;
                  }
               }

               if (!found)
               {
                  if (obj.TabId == result.ActiveTabID)
                  {
                     //Get the widgets for this Tab
                     var dWidgets = from UW in db.TabWidgets
                                    join W in db.Widgets on UW.WidgetId equals W.ID
                                    where UW.TabId == obj.TabId
                                    orderby UW.ColumnNo, UW.OrderNo
                                    select new { Instance = UW, W.Url, Icon = (UW.Icon == null ? W.Icon : UW.Icon) };

                     ArrayList xWidgets = new ArrayList();
                     foreach (var w in dWidgets)
                     {
                        xWidgets.Add(new JSON_UserWidget(w.Instance.Id, w.Instance.ColumnNo, w.Instance.OrderNo, w.Instance.Expanded, w.Instance.Title, w.Instance.State, w.Url, w.Icon, w.Instance.Height));
                     }

                     Tabs.Add(new JSON_Tab(obj.TabId, obj.TabRecord.Title, obj.TabRecord.Icon, obj.TabRecord.PanelWidth_1, obj.TabRecord.PanelWidth_2,
                        obj.TabRecord.PanelWidth_3, obj.TabRecord.PanelWidth_4, obj.Order, GetTabAccessLevel(obj.AccessLevel), (JSON_UserWidget[])xWidgets.ToArray(typeof(JSON_UserWidget)), obj.TabRecord.InnerHTML));
                  }
                  else
                  {
                     Tabs.Add(new JSON_Tab(obj.TabId, obj.TabRecord.Title, obj.TabRecord.Icon, obj.TabRecord.PanelWidth_1, obj.TabRecord.PanelWidth_2,
                        obj.TabRecord.PanelWidth_3, obj.TabRecord.PanelWidth_4, obj.Order, GetTabAccessLevel(obj.AccessLevel), null, obj.TabRecord.InnerHTML));
                  }
               }
            }
         }

         //Remove all tabs they have no permission to access
         for (int i = 0; i < Tabs.Count; i++)
         {
            var AccessLevel = ((JSON_Tab)Tabs[i]).AccessLevel;
            foreach (TabAccessLevel lvl in AccessLevel)
               if (lvl == TabAccessLevel.None)
               {
                  Tabs.RemoveAt(i);
                  i--;
               }
         }

         result.Tabs = (JSON_Tab[])Tabs.ToArray(typeof(JSON_Tab));
         return result;
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = true, XmlSerializeString = true)]
   public JSON_Tab Tab_Refresh(int TabID)
   {
      using (new EntTimedLog(UserName, "JSON:Tab_Refresh",TabID.ToString()))
      {
         var F = new Facade(UserKey, UserName);
         if (F.Tab_CheckReadPermission(TabID))
         {
            using (var db = DatabaseHelper.GetDashboardData())
            {
               //get all the user Tabs and properties
               var dUserTabs = (from UP in db.UserTabs
                                join P in db.Tabs on UP.TabId equals P.ID
                                where UP.UserID == UserKey && UP.Deleted == false && P.ID == TabID                                
                                select new { UP.AccessLevel, UP.TabId, UP.Order, TabRecord = P });
               var dTabInfo = dUserTabs.FirstOrDefault();
               if (dTabInfo != null)
               {
                  var AccessLevel = GetTabAccessLevel(dTabInfo.AccessLevel);
                  foreach (TabAccessLevel lvl in AccessLevel)
                     if (lvl == TabAccessLevel.None)
                     {
                        throw new ApplicationException("You do not have permission to view this tab");
                     } 

                  return new JSON_Tab(dTabInfo.TabId, dTabInfo.TabRecord.Title, dTabInfo.TabRecord.Icon, dTabInfo.TabRecord.PanelWidth_1, dTabInfo.TabRecord.PanelWidth_2,
                           dTabInfo.TabRecord.PanelWidth_3, dTabInfo.TabRecord.PanelWidth_4, dTabInfo.Order, AccessLevel, null, dTabInfo.TabRecord.InnerHTML);
               }

               throw new ApplicationException("No such tab");
            }
         }
         else
         {
            throw new ApplicationException("You do not have permission to access this tab(" + TabID + ")");
         }
      }
   }


   [WebMethod]
   [ScriptMethod(UseHttpGet = true, XmlSerializeString = true)]
   public JSON_Messages GetMessages()
   {
      using (new EntTimedLog(UserName, "JSON:GetMessages"))
      {
         int New = 0;
         ArrayList Messages = new ArrayList();

         DateTime PwdLastSet = NexusMembershipProvider.GetUserPasswordExpiry(UserName);
         if (PwdLastSet.Year > 1)
         {
            var PwdExpire = Math.Round((new TimeSpan(PwdLastSet.AddDays(180).Ticks - DateTime.Now.Ticks)).TotalDays, 0);
            string strPwd = (PwdLastSet.AddDays(180) > DateTime.Now ?
               "Your password expires in " + PwdExpire + " days" :
                  "Your password was last set on " + PwdLastSet.ToString("dd MMM yyyy") + ".");
            strPwd += " Click <a target='_blank' href='https://exchange.nus.edu.sg/iisadmpwd/'>here</a> to change your password";
            Messages.Add(new Message("LDAP", strPwd, (PwdExpire < 10), false));
         }        

         
         if (UserName.ToLower() == @"nusstf\citv2")
         {
            Messages.Add(new Message("APICTA", "This is a testing account, please logout now if you have not been given authorization to access the system", true));
         }

         string UserID = UserInfo.UserID;
         int result = 0;
         using (var db = new DataClassesDataContext(System.Configuration.ConfigurationManager.ConnectionStrings["LMSConnectionString"].ConnectionString))
         {
            foreach (var row in db.upWorkspace_Announcement(UserID))
            {
               Messages.Add(new Message("IVLE", row.CourseCode + " " + row.EventTitle + " - " + row.Description, Functions.StripHtml(row.CourseCode + " " + row.EventTitle + " - " + row.Description), true));
               db.spAnnouncementLog_Ins(row.AnnEventID, UserID, DateTime.Now, ref result);
            }
         }

         using (var db = DatabaseHelper.GetDashboardData())
         {
            var dbMessages = db.ExecuteQuery<DataLayer.Message>(@"
select * from 
Messages M
inner join
(
select MessageID from Message_Roles
where RoleID in (" + strUserRoleID + @")

UNION

select MessageID from Message_Users
where UserID = {0}
) MID
on M.ID=MID.MessageID
where getdate() between StartDate and EndDate
", UserKey);

            foreach (var Msg in dbMessages)
            {
               Messages.Add(new Message(Msg.Title, Msg.Content, Msg.Ticker, Msg.NewDate.Ticks > DateTime.Now.Ticks));
            }
         }

         return new JSON_Messages(Messages.Count, New, Messages);
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public Tab_Widgets Tab_GetWidgets(int TabId)
   {
      using (new EntTimedLog(UserName, "JSON:Tab_GetWidgets", TabId.ToString()))
      {

         using (var db = DatabaseHelper.GetDashboardData())
         {
            var dWidgets = from UW in db.TabWidgets
                           join W in db.Widgets on UW.WidgetId equals W.ID
                           where UW.TabId == TabId
                           orderby UW.ColumnNo, UW.OrderNo
                           select new { Instance = UW, W.Url, Icon = (UW.Icon == null ? W.Icon : UW.Icon) };

            ArrayList xWidgets = new ArrayList();
            foreach (var w in dWidgets)
            {
               xWidgets.Add(new JSON_UserWidget(w.Instance.Id, w.Instance.ColumnNo, w.Instance.OrderNo, w.Instance.Expanded, w.Instance.Title, w.Instance.State, w.Url, w.Icon, w.Instance.Height));
            }
            return new Tab_Widgets(TabId, (JSON_UserWidget[])xWidgets.ToArray(typeof(JSON_UserWidget)));
         }
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public void Tab_SaveTitle(string Title, int TabID)
   {
      using (new EntTimedLog(UserName, "JSON:Tab_SaveTitle", TabID + ":" + Title))
      {
         using (var db = DatabaseHelper.GetDashboardData())
         {
            new Facade(UserKey, UserName).Tab_UpdateTitle(TabID, Title);
         }
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public void Tab_UpdatePosition(string Positions)
   {
      using (new EntTimedLog(UserName, "JSON:Tab_UpdatePositions", Positions))
      {

         //no requirement to check permission because a user can always reorder his tabs
         //called when a tab position is changed
         //{"Positions":"2,1,"}
         string[] strPositions = Positions.Split(",".ToCharArray());
         ArrayList alPosition = new ArrayList();
         foreach (string s in strPositions)
         {
            int val = Typecast.ToInt32(s);
            if (val > 0)
            {
               alPosition.Add(val);
            }
         }

         using (var db = DatabaseHelper.GetDashboardData())
         {
            var dUserTabs = from p in db.UserTabs
                            where p.UserID == UserKey
                            orderby p.TabId
                            select p;

            foreach (var obj in dUserTabs)
            {
               obj.Order = Convert.ToByte(alPosition.IndexOf(obj.TabId) + 1);
            }

            db.SubmitChanges();
         }
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public void Tab_Delete(int DelTabID, int ActiveTabID)
   {
      using (new EntTimedLog(UserName, "JSON:Tab_Delete", DelTabID + ":" + ActiveTabID))
      {
         new Facade(UserKey, UserName).Tab_Delete(DelTabID, ActiveTabID);
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public void Tab_Resize(int TabID, byte C1, byte C2, byte C3, byte C4, string innerHTML)
   {
      using (new EntTimedLog(UserName, "JSON:Tab_Resize", TabID + ":" + C1 + ":" + C2 + ":" + C3 + ":" + C4 + ":" + innerHTML))
      {
         new Facade(UserKey, UserName).Tab_ResizeColumns(TabID, C1, C2, C3, C4, innerHTML);
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public JSON_Tab Tab_Add()
   {
      int TabId = new Facade(UserKey, UserName).Tab_Create();
      using (new EntTimedLog(UserName, "JSON:Tab_Add", TabId.ToString()))
      {
         //get all the user Tabs and properties
         using (var db = DatabaseHelper.GetDashboardData())
         {
            var dUserTabs = from UP in db.UserTabs
                            join P in db.Tabs on UP.TabId equals P.ID
                            orderby P.ID
                            where UP.UserID == UserKey && UP.TabId == TabId
                            select new { UP.AccessLevel, UP.TabId, UP.Order, TabRecord = P };

            var obj = dUserTabs.First();
            return new JSON_Tab(obj.TabId, obj.TabRecord.Title, obj.TabRecord.Icon, obj.TabRecord.PanelWidth_1, obj.TabRecord.PanelWidth_2,
               obj.TabRecord.PanelWidth_3, obj.TabRecord.PanelWidth_4, obj.Order, GetTabAccessLevel(obj.AccessLevel), null, obj.TabRecord.InnerHTML);
         }
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public JSON_UserWidget Tab_AddWidget(int TabId, int WidgetId)
   {
      if (TabAccessLevelFunctions.UserHasPermission(UserKey, TabId, TabAccessLevel.Tab_AddWidgets))
      {
         using (new EntTimedLog(UserName, "JSON:Tab_AddWidget", TabId + ":" + WidgetId))
         {
            using (var db = DatabaseHelper.GetDashboardData())
            {
               var obj = new Facade(UserKey, UserName).Tab_AddWidget(TabId, WidgetId, "");
               var obj_Widget = db.Widgets.Single(p => p.ID == obj.WidgetId);

               return new JSON_UserWidget(obj.Id, obj.ColumnNo, obj.OrderNo, obj.Expanded, obj.Title, obj.State, obj_Widget.Url, obj_Widget.Icon, obj.Height);
            }
         }
      }
      else
      {
         throw new Exception("You do not have permission to perform this action");
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public JSON_UserWidget Tab_AddRSSWidget(int TabId, string url)
   {
      if (TabAccessLevelFunctions.UserHasPermission(UserKey, TabId, TabAccessLevel.Tab_AddWidgets))
      {
         if (url.Length > 0)
         {
            using (new EntTimedLog(UserName, "JSON:Tab_AddRSSWidget", TabId + ":" + url))
            {
               int WidgetId = 3;

               using (var db = DatabaseHelper.GetDashboardData())
               {

                  /* from proxyasync getrss */
                  ArrayList Items = new ArrayList();

                  string Title = "RSS";
                  string Icon = null;
                  try
                  {
                     if (url.Length > 0)
                     {
                        RssFeed feed = RssFeed.Read(url);

                        Icon = url.ToLower().Replace("http://", "");
                        try
                        {
                           Icon = Icon.Substring(0, Icon.IndexOf("/"));
                           Icon = "http://" + Icon + "/favicon.ico";
                        }
                        catch
                        {
                           Icon = null;
                        }

                        int ChannelLen = feed.Channels.Count;
                        for (int i = 0; i < ChannelLen; i++)
                        {
                           var ChannelElement = (RssChannel)feed.Channels[i];
                           Title = ChannelElement.Title;

                           int ItemLen = ChannelElement.Items.Count;

                           for (int j = 0; j < ItemLen; j++)
                           {
                              var Element = ChannelElement.Items[j];
                              var Item = new RssItem();
                              Item.Description = ProxyAsync.StripTags(Element.Description);
                              Item.Link = Element.Link.ToString();
                              Item.Title = ProxyAsync.StripTags(Element.Title);
                              Items.Add(Item);
                           }
                        }
                        Context.Cache.Insert(ProxyAsync.CACHE_KEY + url, Items, null, DateTime.MaxValue, TimeSpan.FromMinutes(15));
                     }
                  }
                  catch
                  {
                  }

                  var obj = new Facade(UserKey, UserName).Tab_AddWidget(TabId, WidgetId, "0," + url, Title, Icon);
                  var obj_Widget = db.Widgets.Single(p => p.ID == obj.WidgetId);

                  return new JSON_UserWidget(obj.Id, obj.ColumnNo, obj.OrderNo, obj.Expanded, obj.Title, obj.State, obj_Widget.Url, (obj.Icon == null || obj.Icon.Length < 1 ? obj_Widget.Icon : obj.Icon), obj.Height);
               }
            }
         }
         else
         {
            throw new Exception("Please enter a RSS Url");
         }
      }
      else
      {
         throw new Exception("You do not have permission to perform this action");
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public void Tab_UpdateWidgetOrder(int TabId, int Col, string Order)
   {
      using (new EntTimedLog(UserName, "JSON:Tab_UpdateWidgetOrder", TabId + ":" + Col + ":" + Order))
      {
         //called when a tab position is changed
         //widgetinstanceid:col:order,widgetinstanceid:col:order,
         //{"TabId":1,"Col":2,"Order":"7,6,4,"}
         new Facade(UserKey, UserName).Tab_ReorderWidget(TabId, Col, Order);
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public Menu_Category[] Menu_GetCategory(int CategoryID)
   {
      using (new EntTimedLog(UserName, "JSON:Menu_GetCategory", CategoryID.ToString()))
      {
         ArrayList result = new ArrayList();

         using (var db = DatabaseHelper.GetDashboardData())
         {
            var categories = from p in db.WidgetCategories
                             orderby p.Order, p.Category
                             select new { p.Category, p.ID };

            foreach (var obj in categories)
            {
               result.Add(new Menu_Category(obj.Category, obj.ID));
            }
         }

         return (Menu_Category[])result.ToArray(typeof(Menu_Category));
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public Menu_Widgets[] Menu_GetCategoryWidgets(int CategoryID)
   {
      using (new EntTimedLog(UserName, "JSON:Menu_GetCategoryWidgets", CategoryID.ToString()))
      {
         ArrayList result = new ArrayList();
         using (var db = DatabaseHelper.GetDashboardData())
         {
            var widgets = db.ExecuteQuery<Widget>(@"
select W.* from 
Widget W left outer join WidgetPermission WP
on W.ID=WP.WidgetID
where 
W.CategoryID={0} and W.Enabled=1 and
(WP.WidgetID is null
or WP.RoleID in (" + strUserRoleID + @"))
order by W.[OrderNo], W.[Name]", CategoryID);

            foreach (var obj in widgets)
            {
               result.Add(new Menu_Widgets(obj.Name, obj.Icon, obj.ID));
            }
         }

         return (Menu_Widgets[])result.ToArray(typeof(Menu_Widgets));
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public Menu_WidgetInfo Menu_GetWidgetInfo(int WidgetID)
   {
      using (new EntTimedLog(UserName, "JSON:Menu_GetWidgetInfo", WidgetID.ToString()))
      {
         using (var db = DatabaseHelper.GetDashboardData())
         {
            var w = db.Widgets.Single(p => p.ID == WidgetID);

            return new Menu_WidgetInfo(w.Name, w.Icon, w.ID, w.Url, w.Description);
         }
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public string[] Menu_GetThemes()
   {
      return null;
      using (new EntTimedLog(UserName, "JSON:Menu_GetThemes", ""))
      {
         ArrayList Items = new ArrayList();
         DirectoryInfo DI = new DirectoryInfo(Server.MapPath(Path.Combine(HttpContext.Current.Request.ApplicationPath, "App_Themes")));
         foreach (DirectoryInfo C in DI.GetDirectories())
         {
            Items.Add(C.Name);
         }
         Items.Sort();
         return (string[])Items.ToArray(typeof(string));
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public void Widget_UpdateProperty(int TabId, int WidgetInstanceId, string Property, string Value)
   {
      using (new EntTimedLog(UserName, "JSON:Widget_UpdateProperty", TabId + ":" + WidgetInstanceId + ":" + Property + ":" + Value))
      {
         new Facade(UserKey, UserName).WidgetInstance_UpdateProperty(TabId, WidgetInstanceId, Property, Value);
      }
   }

   [WebMethod(EnableSession = true)]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public void Widget_UpdateProperties(int TabId, int WidgetInstanceId, System.Collections.Generic.Dictionary<string, string> wProperties)
   {
      using (new EntTimedLog(UserName, "JSON:Widget_UpdateProperties", TabId + ":" + WidgetInstanceId))
      {
         RSA_Session RSA = new RSA_Session();
         RSA.InitCrypto();
         var theKeys = wProperties.Keys;
         for (var i = 0; i < theKeys.Count; i++)
         {
            string keyName = theKeys.ElementAt(i);
            if (keyName.ToLower().IndexOf("enc_") == 0)
            {
               wProperties[keyName] = RSA.DecryptToText(wProperties[keyName]);
            }
         }
         new Facade(UserKey, UserName).WidgetInstance_UpdateProperties(TabId, WidgetInstanceId, wProperties);
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public string Widget_UpdateIframe(int TabId, int WidgetInstanceId, System.Collections.Generic.Dictionary<string, string> wProperties)
   {
      string Icon = "";
      using (new EntTimedLog(UserName, "JSON:Widget_UpdateIframe", TabId + ":" + WidgetInstanceId))
      {
         new Facade(UserKey, UserName).WidgetInstance_UpdateProperties(TabId, WidgetInstanceId, wProperties);

         try
         {
            Icon = wProperties["URL"];
            //try to grab the icon and title of page
            if (Icon != null && Icon.Length > 0)
            {
               Icon = Icon.ToLower().Replace("http://", "");
               if (Icon.IndexOf("/") > -1)
                  Icon = Icon.Substring(0, Icon.IndexOf("/"));

               Icon = "http://" + Icon + "/favicon.ico";

               using (var db = DatabaseHelper.GetDashboardData())
               {
                  db.ExecuteCommand("update TabWidgets set Icon={0} where Id={1}", Icon, WidgetInstanceId);
               }
            }
         }
         catch
         {
         }
      }
      return Icon;
   }


   [WebMethod]
   [ScriptMethod(UseHttpGet = true, XmlSerializeString = true)]
   public JSON_UserWidget Widget_Refresh(int TabID, int WidgetId)
   {
      using (new EntTimedLog(UserName, "JSON:Widget_Refresh", TabID + ":" + WidgetId))
      {
         var F = new Facade(UserKey, UserName);
         if (F.Tab_CheckReadPermission(TabID))
         {
            using (var db = DatabaseHelper.GetDashboardData())
            {
               var p = from UW in db.TabWidgets
                       join W in db.Widgets on UW.WidgetId equals W.ID
                       where UW.TabId == TabID && UW.Id == WidgetId
                       select new { Instance = UW, W.Url, Icon = (UW.Icon == null ? W.Icon : UW.Icon) };

               if (p.Count() > 0)
               {
                  var w = p.First();
                  return new JSON_UserWidget(w.Instance.Id, w.Instance.ColumnNo, w.Instance.OrderNo, w.Instance.Expanded, w.Instance.Title, w.Instance.State, w.Url, w.Icon, w.Instance.Height);
               }
               else
               {
                  //log hacking attempt
                  ActionValidator.ChkValid(ActionValidator.ActionTypeEnum.FailAction);
                  return new JSON_UserWidget();
               }
            }
         }
         else
         {
            throw new ApplicationException("You do not have permission to access this widget(" + TabID + ":" + WidgetId + ")");
         }
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public int Widget_Delete(int TabId, int WidgetId)
   {
      using (new EntTimedLog(UserName, "JSON:Widget_Delete", TabId + ":" + WidgetId))
      {
         new Facade(UserKey, UserName).Tab_DeleteWidget(TabId, WidgetId);
         return 0;
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public void User_UpdateActiveTab(int TabId)
   {
      using (new EntTimedLog(UserName, "JSON:User_UpdateActiveTab", TabId.ToString()))
      {
         using (var db = DatabaseHelper.GetDashboardData())
         {
            var UserSetting = db.UserSettings.Single(p => p.UserId == UserKey);
            UserSetting.ActiveTab = TabId;
            db.SubmitChanges();
         }
      }
   }

   [WebMethod]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public string User_UpdateProfile(string FullName)
   {
      try
      {
         Profile.Fullname = FullName;
         Profile.Save();
         return Server.HtmlEncode(FullName); ;
      }
      catch (Exception ex)
      {
         return "[!ERROR!]" + ex.Message;
      }
   }

   private TabAccessLevel[] GetTabAccessLevel(int lvl)
   {
      return TabAccessLevelFunctions.GetAccessLevels(lvl);
   }

   [WebMethod(EnableSession = true)]
   [ScriptMethod(UseHttpGet = true, XmlSerializeString = true)]
   public RSA_Token getRSAToken()
   {
      RSA_Session s = new RSA_Session();
      var theSession = HttpContext.Current.Session;
      theSession["x"] = "y";
      s.GenerateKeys();
      s.InitCrypto();
      var x = s.ExportParameters(false);

      RSA_Token result = new RSA_Token();

      result.Exponent = BitConverter.ToString(x.Exponent).Replace("-", "");
      result.Modulus = BitConverter.ToString(x.Modulus).Replace("-", "");
      return result;
   }

   [WebMethod(EnableSession = true)]
   [ScriptMethod(UseHttpGet = false, XmlSerializeString = true)]
   public string RSADecrypt(string value)
   {
      return RSA_Session.DecryptValue(value);
   }
}

#region JSON Objects
public class RSA_Token
{
   public string Exponent = "";
   public string Modulus = "";
   public RSA_Token()
   {
   }
}
public class JSON_Tabs
{
   public int ActiveTabID = 0;
   public JSON_Tab[] Tabs = null;
   public JSON_Tabs()
   {
   }
}

public class JSON_Tab
{
   public int id = 0;
   public string Title = "Title";
   public string Icon = "";
   public int PanelWidth_1 = 0;
   public int PanelWidth_2 = 0;
   public int PanelWidth_3 = 0;
   public int PanelWidth_4 = 0;
   public int Order = 0;
   public string InnerHTML = "";

   public TabAccessLevel[] AccessLevel = new TabAccessLevel[1] { TabAccessLevel.None };

   public JSON_UserWidget[] Widgets = null;

   public JSON_Tab(int Id, string title, string icon, int panelwidth_1, int panelwidth_2,
      int panelwidth_3, int panelwidth_4, int order, TabAccessLevel[] accesslevel,
      JSON_UserWidget[] widgets, string innerhtml)
   {
      id = Id;
      Title = title;
      Icon = icon;
      PanelWidth_1 = panelwidth_1;
      PanelWidth_2 = panelwidth_2;
      PanelWidth_3 = panelwidth_3;
      PanelWidth_4 = panelwidth_4;
      Order = order;
      AccessLevel = accesslevel;
      Widgets = widgets;
      InnerHTML = (innerhtml == null ? "" : innerhtml);
   }
}

public class JSON_UserWidget
{
   public int id = 0;
   public int ColumnNo = 0;
   public int OrderNo = 0;
   public bool Expanded = false;
   public string Title = "";
   public string URL = "";
   public string Icon = "";
   public string State = "";
   public int Height = 0;

   public JSON_UserWidget()
   {
   }

   public JSON_UserWidget(int Id, int columnno, int orderno, bool expanded, string title, string state, string url, string icon, int height)
   {
      id = Id;
      ColumnNo = columnno;
      OrderNo = orderno;
      Expanded = expanded;
      Title = title;
      State = state;
      URL = url;
      Icon = icon;
      Height = height;

      System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
      try
      {
         doc.LoadXml(State);
         foreach (System.Xml.XmlNode Node in doc.ChildNodes)
         {
            ScanXml(Node);
         }
         State = doc.InnerXml;
      }
      catch
      {
      }
   }

   private void ScanXml(System.Xml.XmlNode node)
   {
      if (node.Name.ToLower().IndexOf("enc_") == 0)
      {
         node.ChildNodes[0].Value = "";
      }
      foreach (System.Xml.XmlNode sub in node.ChildNodes)
      {
         ScanXml(sub);
      }
   }
}

public class Menu_Category
{
   public string Category = "";
   public int ID = 0;

   public Menu_Category(string category, int id)
   {
      Category = category;
      ID = id;
   }
}

public class Menu_Widgets
{
   public string Title = "";
   public string Image = "";
   public int ID = 0;

   public Menu_Widgets(string title, string image, int id)
   {
      Title = title;
      Image = image;
      ID = id;
   }
}

public class Menu_WidgetInfo
{
   public string Title = "";
   public string Image = "";
   public int ID = 0;
   public string URL = "";
   public string Description = "";

   public Menu_WidgetInfo(string title, string image, int id, string url, string description)
   {
      Title = title;
      Image = image;
      ID = id;
      URL = url;
      Description = description;
   }
}

public class Tab_Widgets
{
   public int TabID = 0;
   public JSON_UserWidget[] Widgets = null;

   public Tab_Widgets(int tabid, JSON_UserWidget[] widgets)
   {
      TabID = tabid;
      Widgets = widgets;
   }
}

public class JSON_Messages
{
   public int Total = 0;
   public int New = 0;
   public Message[] Messages = null;

   public JSON_Messages(int Total, int New, Message[] Messages)
   {
      this.Total = Total;
      this.New = New;
      this.Messages = Messages;
   }
   public JSON_Messages(int Total, int New, ArrayList Messages)
   {
      this.Total = Total;
      this.New = New;
      this.Messages = (Message[])Messages.ToArray(typeof(Message));
   }
}

public class Message
{
   public string Title = "";
   public string Description = "";
   public string TickerMessage = "";
   public bool inTicker = false;
   public bool isNew = false;
   public Message(string Title, string Description, bool inTicker, bool isNew)
   {
      this.Title = Title;
      this.Description = Description;
      this.TickerMessage = Description;
      this.inTicker = inTicker;
   }
   public Message(string Title, string Description, string TickerMessage, bool isNew)
   {
      this.Title = Title;
      this.Description = Description;
      if (TickerMessage.Length > 0)
      {
         this.inTicker = true;
         this.TickerMessage = TickerMessage;
      }
      else
      {
         this.inTicker = false;
         this.TickerMessage = "";
      }
   }
   public Message(string Title, string Description, bool isNew)
   {
      this.Title = Title;
      this.Description = Description;
   }
}
#endregion